﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows;
using System.Data;
using DSPL.Services;
using DSPL.Services.Services;
using DSPL.Contracts;
using DSPL.Contracts.Common;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Media;
using DSPL.Common.CommonControls.Controls;
using DSPL.Contracts.Interfaces;
using DSPL.Contracts.ViewModel;
using DSPL.Contracts.Command;
using DSPL.Finac.Common;
using DSPL.Common;


namespace DSPL.Finac.ViewModel
{
    public class CustomerMasterViewModel : BaseViewModel
    {
        #region Private Variables

        private DataTable _dtDebtorTax;
        private DataTable _dtPriceLevel;
        private DataTable _dtStatus;       
        private bool isCusCodeFocused;
        private bool isCusNameFocused;
        private bool isStatusFocused;
        private bool isCusAdvCodeFocused;
        private bool isCusCntCodeFocused;
        private bool isRankCodeFocused;
        private bool isSalesRepFocused;
        private bool isGainLossFocused;
        private bool isCustomerGroupFocused;
        private bool isAreaFocused;
        private bool isPriceLevelFocused;
        private bool isCreditPeriodChecked;
        private bool isTaxReadOnly;
        private ICommand taxRegClick;
        private ICommand taxCodeLostFocus;
        private ICommand curCodeLostFocus;
        private Visibility _isGainAccVisible;
        private Visibility _isPriceLevelTextVisible;
        private Visibility _isPriceLevelGridVisible;
        private int _PriceLevelStatus;

        #endregion

        #region Properties

        public bool IsCusCodeFocused
        {
            get { return isCusCodeFocused; }
            set
            {
                isCusCodeFocused = value;
                this.OnPropertyChanged("IsCusCodeFocused");

            }
        }

        public bool IsCusNameFocused
        {
            get { return isCusNameFocused; }
            set
            {
                isCusNameFocused = value;
                this.OnPropertyChanged("IsCusNameFocused");

            }
        }

        public bool IsStatusFocused
        {
            get { return isStatusFocused; }
            set
            {
                isStatusFocused = value;
                this.OnPropertyChanged("IsStatusFocused");

            }
        }

        public bool IsCusAdvCodeFocused
        {
            get { return isCusAdvCodeFocused; }
            set
            {
                isCusAdvCodeFocused = value;
                this.OnPropertyChanged("IsCusAdvCodeFocused");

            }
        }

        public bool IsCusCntCodeFocused
        {
            get { return isCusCntCodeFocused; }
            set
            {
                isCusCntCodeFocused = value;
                this.OnPropertyChanged("IsCusCntCodeFocused");
            }
        }


        public bool IsGainLossFocused
        {
            get { return isGainLossFocused; }
            set
            {
                isGainLossFocused = value;
                this.OnPropertyChanged("IsGainLossFocused");

            }
        }


        public bool IsSalesRepFocused
        {
            get { return isSalesRepFocused; }
            set
            {
                isSalesRepFocused = value;
                this.OnPropertyChanged("IsSalesRepFocused");

            }
        }
    

        public bool IsCustomerGroupFocused
        {
            get { return isCustomerGroupFocused; }
            set
            {
                isCustomerGroupFocused = value;
                this.OnPropertyChanged("IsCustomerGroupFocused");

            }
        }

        public bool IsAreaCodeFocused
        {
            get { return isAreaFocused; }
            set
            {
                isAreaFocused = value;
                this.OnPropertyChanged("IsAreaCodeFocused");

            }
        }

        public bool IsRankCodeFocused
        {
            get { return isRankCodeFocused; }
            set
            {
                isRankCodeFocused = value;
                this.OnPropertyChanged("IsRankCodeFocused");
            }
        }

        public bool IsPriceLevelFocused
        {
            get { return isPriceLevelFocused; }
            set
            {
                isPriceLevelFocused = value;
                this.OnPropertyChanged("IsPriceLevelFocused");
            }
        }
        

        public bool IsCreditPeriodChecked
        {
            get { return isCreditPeriodChecked; }
            set
            {
                isCreditPeriodChecked = value;
                this.OnPropertyChanged("IsCreditPeriodChecked");

            }
        }

        public bool IsCreditLimitChecked
        {
            get { return isCreditPeriodChecked; }
            set
            {
                isCreditPeriodChecked = value;
                this.OnPropertyChanged("IsCreditPeriodChecked");
            }
        }


        public bool IsTaxReadOnly
        {
            get { return isTaxReadOnly; }
            set { isTaxReadOnly = value; }
        }

        public DataTable DtDebtorTax
        {
            get { return _dtDebtorTax; }
            set
            {
                _dtDebtorTax = value;
                this.OnPropertyChanged("DtDebtorTax");
            }
        }


        public DataTable DtStatus
        {
            get { return _dtStatus; }
            set
            {
                _dtStatus = value;
                this.OnPropertyChanged("DtStatus");
            }
        }


        public Visibility IsGainAccVisible
        {
            get { return _isGainAccVisible; }
            set
            {
                _isGainAccVisible = value;
                this.OnPropertyChanged("IsGainAccVisible");
            }
        }

        public Visibility IsPriceLevelTextVisible
        {
            get { return _isPriceLevelTextVisible; }
            set
            {
                _isPriceLevelTextVisible = value;
                this.OnPropertyChanged("IsPriceLevelTextVisible");
            }
        }

        public Visibility IsPriceLevelGridVisible
        {
            get { return _isPriceLevelGridVisible; }
            set
            {
                _isPriceLevelGridVisible = value;
                this.OnPropertyChanged("IsPriceLevelGridVisible");
            }
        }

        public DataTable DtPriceLevel
        {
            get
            {
                return _dtPriceLevel;
            }
            set
            {
                _dtPriceLevel = value;
                this.OnPropertyChanged("DtPriceLevel");
            }
        }
        #endregion

        #region Define relay commands

        public ICommand TaxRegClick
        {
            get
            {
                if (this.taxRegClick == null)
                    this.taxRegClick = new RelayCommand(TaxRegClicked);

                return this.taxRegClick;
            }
        }

        public ICommand TaxCodeLostFocus
        {
            get
            {
                if (this.taxCodeLostFocus == null)
                    this.taxCodeLostFocus = new RelayCommand(TaxCodeLostFocusExecuted);

                return this.taxCodeLostFocus;
            }
        }

        public ICommand CurCodeLostFocus
        {
            get
            {
                if (this.curCodeLostFocus == null)
                    this.curCodeLostFocus = new RelayCommand(CurrencyCodeLostFocusExecuted);

                return this.curCodeLostFocus;
            }
        }

        #endregion
       
        #region Constructor
        public CustomerMasterViewModel()
            : base()
        {
            MessageTitle = "Customer Master";
        }
        #endregion

        protected override void RefreshExternalDataObjectsExecueted(object obj)
        {
            base.RefreshExternalDataObjectsExecueted(obj);          
            SetTaxRegistrationData();
            SetPriceLevels();

            if (FormMode == Modes.New)
            {

                CurrentRow["Status"] = 1;
                OnPropertyChanged("CurrentRow");

            }

        }

        private void TaxRegClicked(object obj)
        {
            SetTaxRegistrationData();
        }


        /// <summary>
        /// To validate mandatory fields
        /// </summary>
        /// <returns></returns>
        /// <summary>
        /// Validate mandatory data before save
        /// </summary>
        /// <param name="obj"></param>
        protected override void PreDataValidateExecuted(object obj)
        {
            IsCusCodeFocused = false;
            IsCusNameFocused = false;
            IsStatusFocused = false;
            IsCusCntCodeFocused = false;
            IsCusAdvCodeFocused = false;
            IsGainLossFocused = false;
            IsCustomerGroupFocused = false;
            IsSalesRepFocused = false;
            IsAreaCodeFocused = false;
            IsRankCodeFocused = false;
            IsPriceLevelFocused = false;

            var messageService = new MessageService();
            if (CurrentRow["DebCode"].ToString().Trim() == string.Empty)
            {
                messageService.ShowMessage(MessageText.DebtorCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsCusCodeFocused = true;
                this.IsValid = false;
                return;
            }

            if (CurrentRow["DebName"].ToString().Trim() == string.Empty)
            {
                messageService.ShowMessage(MessageText.DebtorNameNotEmpty, MessageTitle, MessageType.InfoOK);
                IsCusNameFocused = true;
                this.IsValid = false;
                return;
            }

            if (CurrentRow["Status"].ToString().Trim() == string.Empty)
            {
                messageService.ShowMessage(MessageText.DebtorTypeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsStatusFocused = true;
                this.IsValid = false;
                return;
            }

            if (CurrentRow["DebCntAcc"].ToString().Trim() == string.Empty)
            {
                messageService.ShowMessage(MessageText.DebtorAcCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsCusCntCodeFocused = true;
                this.IsValid = false;
                return;
            }

            if (CurrentRow["DebAdvAcc"].ToString().Trim() == string.Empty)
            {
                messageService.ShowMessage(MessageText.DebtorAdvAcCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsCusAdvCodeFocused = true;
                this.IsValid = false;
                return;
            }

            if ((IsGainAccVisible == Visibility.Visible) && (CurrentRow["DebGainLos"].ToString().Trim() == string.Empty))
            {
                messageService.ShowMessage(MessageText.DebtorGainLossAcCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsGainLossFocused = true;
                this.IsValid = false;
                return;
            }

            if  (CurrentRow["DbGrPk"]==DBNull.Value || Convert.ToInt32(CurrentRow["DbGrPk"]) == 0)
            {
                messageService.ShowMessage(MessageText.DebtorGroupCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsCustomerGroupFocused = true;
                this.IsValid = false;
                return;
            }

            if (CurrentRow["AreaPk"] == DBNull.Value || Convert.ToInt32(CurrentRow["AreaPk"]) == 0)
            {
                messageService.ShowMessage(MessageText.AreaCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsAreaCodeFocused = true;
                this.IsValid = false;
                return;
            }

            if (CurrentRow["RepPk"] == DBNull.Value || Convert.ToInt32(CurrentRow["RepPk"]) == 0)
            {
                messageService.ShowMessage(MessageText.RepCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsSalesRepFocused = true;
                this.IsValid = false;
                return;
            }

            else
            {
                var repMasterRetrieve = new MasterReadService();

                if (!repMasterRetrieve.IsSalesRepActive(Convert.ToInt32(CurrentRow["RepPk"])))
                {
                    messageService.ShowMessage(MessageText.SalesRepInactive, MessageTitle, MessageType.InfoOK);
                    IsSalesRepFocused = true;
                    this.IsValid = false;
                    return;
                }
            }

            if (CurrentRow["RankPk"] == DBNull.Value || Convert.ToInt32(CurrentRow["RankPk"]) == 0)
            {
                messageService.ShowMessage(MessageText.RankCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsRankCodeFocused = true;
                this.IsValid = false;
                return;
            }

            DtPriceLevel.AcceptChanges();
            if (_PriceLevelStatus == 1)
            {
                if (DtPriceLevel.Select("CurCode<>'' AND PrilCode<>''").Length == 0)
                {
                    MessageBox.Show("Price Level Code cannot be empty.", MessageTitle, MessageBoxButton.OK, MessageBoxImage.Information);
                    
                    if (DtPriceLevel.Rows.Count == 0)
                    {
                        DataRow drNewPrice = _dtPriceLevel.NewRow();
                        drNewPrice["CurCode"] = "";
                        drNewPrice["PrilCode"] = "";
                        drNewPrice["DebPk"] =(CurrentRow["DebPk"]==DBNull.Value?0 :Convert.ToInt32(CurrentRow["DebPk"]));
                        drNewPrice["DebCode"] = Convert.ToString(CurrentRow["DebCode"]);
                        _dtPriceLevel.Rows.Add(drNewPrice);
                    }
                    this.IsValid = false;
                    return ;
                }
            }

            else
            {
                if (CurrentRow["PriLvlPk"] == DBNull.Value || Convert.ToInt32(CurrentRow["PriLvlPk"]) == 0)
                {
                    messageService.ShowMessage(MessageText.PriceLevelNotEmpty, MessageTitle, MessageType.InfoOK);
                    IsPriceLevelFocused = true;
                    this.IsValid = false;
                    return;
                }
                else
                {
                    var priceMasterRetrieve = new MasterReadService();

                    if (!priceMasterRetrieve.IsPriceLevelActive(Convert.ToInt32(CurrentRow["PriLvlPk"])))
                    {
                        messageService.ShowMessage(MessageText.PriceLevelInactive, MessageTitle, MessageType.InfoOK);
                        IsPriceLevelFocused = true;
                        this.IsValid = false;
                        return;
                    }
                }
            }

            DtDebtorTax.AcceptChanges();
            DtPriceLevel.AcceptChanges();
                
            DataTable dtDebtorTax = DtDebtorTax.DefaultView.ToTable();

            foreach (DataRow drDebtorTax in dtDebtorTax.Rows)
            {
                if ((drDebtorTax["TaxCode"].ToString().Trim() == string.Empty) && (drDebtorTax["TaxRegNo"].ToString().Trim() == string.Empty))
                    continue;
                if ((drDebtorTax["TaxCode"].ToString().Trim() == string.Empty) || (drDebtorTax["TaxRegNo"].ToString().Trim() == string.Empty))
                {
                    messageService.ShowMessage(MessageText.TaxCodeRegNoNotEmpty, MessageTitle, MessageType.InfoOK);
                    this.IsValid = false;
                    return;
                }
            }

            DataRow[] validRecords = DtDebtorTax.Select("TaxCode <>''");
            if (CurrentRow["TaxReg"] !=DBNull.Value && (Convert.ToInt32(CurrentRow["TaxReg"]) == 1) && (validRecords.Length == 0))
            {
                messageService.ShowMessage(MessageText.InvalidTaxData, MessageTitle, MessageType.InfoOK);
                this.IsValid = false;
                if (DtDebtorTax.Rows.Count == 0)
                {
                    DataRow drNewTax = DtDebtorTax.NewRow();
                    drNewTax["TaxCode"] = "";
                    drNewTax["TaxRegNo"] = "";
                    DtDebtorTax.Rows.Add(drNewTax);
                }
                return;
            }

            foreach (DataRow drPriceLevel in DtPriceLevel.Rows)
            {
                if ((drPriceLevel["CurCode"].ToString().Trim() == string.Empty) && (drPriceLevel["PrilCode"].ToString().Trim() == string.Empty))
                    continue;
                if ((drPriceLevel["CurCode"].ToString().Trim() == string.Empty) || (drPriceLevel["PrilCode"].ToString().Trim() == string.Empty))
                {
                    messageService.ShowMessage(MessageText.CurCodePriceCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                    this.IsValid = false;
                    return;
                }
            }



            this.IsValid = true;
            return;
        }

        /// <summary>
        /// To delete related records from child tables before deletes the master data.
        /// </summary>
        /// <returns></returns>
        protected override void PreDataDeleteExecuted(object obj)
        {
            var commonService = new MasterWriteService();
            var sqlTran = this.SqlTran;
            if (!commonService.DeleteDebtorSpecificData(Convert.ToInt32(CurrentRow["DebPk"]), ref sqlTran))
            {
                this.IsValid = false;
            }
            else
            {
                this.IsValid = true;
                this.SqlTran = sqlTran;
            }
        }

        /// <summary>
        /// To build up the insert statements to update related child tables.
        /// </summary>
        /// <param name="writeData"></param>
        /// <returns></returns>
        /// 
        protected override void PostDataUpdateExecuted(object obj)
        {
            var commonService = new MasterWriteService();
            var sqlTran = this.SqlTran;
            if (!commonService.UpdateDebtorTaxData(CurrentRow, DtDebtorTax, ref sqlTran))
            {
                this.IsValid = false;
            }
            else if (!commonService.UpdateDebtorPriceData(CurrentRow, DtPriceLevel, ref sqlTran))
            {
                this.IsValid = false; 
               
            }
            else
            {
                this.IsValid = true;
                this.SqlTran = sqlTran;
            }
        }


        /// <summary>
        /// To build up the insert statements to update related child tables.
        /// </summary>
        /// <param name="writeData"></param>
        /// <returns></returns>
        /// 
        protected override void PostDataInsertExecuted(object obj)
        {
            var commonService = new MasterWriteService();
            var sqlTran = this.SqlTran;
            if (!commonService.UpdateDebtorTaxData(CurrentRow, DtDebtorTax, ref sqlTran))
            {
                this.IsValid = false;
            }
            else if (!commonService.UpdateDebtorPriceData(CurrentRow, DtPriceLevel, ref sqlTran))
            {
                this.IsValid = false;

            }
            else
            {
                this.IsValid = true;
                this.SqlTran = sqlTran;
            }
        }

        private void TaxCodeLostFocusExecuted(object obj)
        {
            string taxCode = ((TxtMaster)obj).Code;
            var messageService = new MessageService();
            if (taxCode != string.Empty)
            {
                DataRow[] duplicateRows = _dtDebtorTax.Select("TaxCode='" + taxCode + "'");
                if (duplicateRows.Length >= 1)
                {
                    messageService.ShowMessage(MessageText.TaxCodeDuplicate, MessageTitle, MessageType.InfoOK);

                    DataRow drLastRow = duplicateRows[duplicateRows.Length - 1];
                    ((TxtMaster)obj).Code = "";
                }
            }
        }

        private void CurrencyCodeLostFocusExecuted(object obj)
        {
            string currencyCode = ((TxtMaster)obj).Code;
            var messageService = new MessageService();
            if (currencyCode != string.Empty)
            {
                DataRow[] duplicateRows = _dtPriceLevel.Select("CurCode='" + currencyCode + "'");
                if (duplicateRows.Length >= 1)
                {
                    messageService.ShowMessage(MessageText.CurrencyCodeDuplicate, MessageTitle, MessageType.InfoOK);

                    DataRow drLastRow = duplicateRows[duplicateRows.Length - 1];
                    ((TxtMaster)obj).Code = "";
                }
            }
        }

        

        private void SetTaxRegistrationData()
        {
            int CusCode = 0;
            bool isEnabled = true;
            if ( CurrentRow["TaxReg"]!=DBNull.Value && Convert.ToInt32(CurrentRow["TaxReg"]) ==1)
            {
                CusCode = (CurrentRow["DebPk"] == DBNull.Value ? 0 : (int)CurrentRow["DebPk"]);
                isEnabled = true;
            }
            else
            {
                CusCode = 0;
                isEnabled = false;
            }

            var getMasterData = new MasterReadService();
            DtDebtorTax = getMasterData.GetCustomerTaxData(CusCode);

            IsTaxReadOnly = !isEnabled;
        }


        protected override void SetDataSourcesAndProperties()
        {
            _dtStatus = new DataTable();
            _dtStatus.Columns.Add("Status");
            _dtStatus.Columns.Add("Title");
            _dtStatus.Rows.Add(1, "Active");
            _dtStatus.Rows.Add(0, "Inactive");
            _dtStatus.Rows.Add(2, "Blacklist");
                       
            SetPriceLevels();
        }

        private void TextLostFocusExecuted(object obj)
        {

        }
                

        protected override void EnableDisableSpecificControls()
        {
            base.EnableDisableSpecificControls();

            if (GlobalVariables.SystemCurrency == "LOCAL")
            {
                IsGainAccVisible = Visibility.Hidden;
            }
            else
            {
                IsGainAccVisible = Visibility.Visible;
            }

           
            if (_PriceLevelStatus == 1)
            {
                IsPriceLevelTextVisible = Visibility.Hidden;
                IsPriceLevelGridVisible = Visibility.Visible;
            }
            else
            {
                IsPriceLevelTextVisible = Visibility.Visible;
                IsPriceLevelGridVisible = Visibility.Hidden;
            }
        }

        protected override void PreDataInsertExecuted(object obj)
        {
            if (CurrentRow["TaxReg"] == DBNull.Value)
            {
                CurrentRow["TaxReg"] = 0;
            }

            if (CurrentRow["ChkCrdPrd"] == DBNull.Value)
            {
                CurrentRow["ChkCrdPrd"] = 0;
            }

            if (CurrentRow["ChkCrdLmt"] == DBNull.Value)
            {
                CurrentRow["ChkCrdLmt"] = 0;
            }
        }

        private void SetPriceLevels()
        {
            var commonService = new MasterReadService();
            var dtPriceStatus = commonService.GetPriceLevelStatus();
            _PriceLevelStatus = Convert.ToInt32(dtPriceStatus.Rows[0]["Status"]);

            int debtorPk = 0;

            if (CurrentRow != null)
            {
                debtorPk = (CurrentRow["DebPk"] == DBNull.Value ? 0 : Convert.ToInt32(CurrentRow["DebPk"]));
            }
            DtPriceLevel = commonService.GetDebtorPriceLevel(debtorPk);
        }

       

    }
}
    


